package com.cskaoyan.service.wx.coupon.impl;

import com.cskaoyan.bean.*;
import com.cskaoyan.bean.vo.wx.coupon.*;
import com.cskaoyan.bean.vo.wx.coupon.WxCouponListVo;
import com.cskaoyan.mapper.MarketCartMapper;
import com.cskaoyan.mapper.MarketCouponMapper;
import com.cskaoyan.mapper.MarketCouponUserMapper;
import com.cskaoyan.mapper.MarketGoodsMapper;
import com.cskaoyan.service.wx.coupon.WxCouponService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @author MoJunXiang
 * @since 2022/09/11 20:00
 */
@Service
public class WxCouponServiceImpl implements WxCouponService {

    @Autowired
    MarketCouponMapper marketCouponMapper;
    @Autowired
    MarketCouponUserMapper marketCouponUserMapper;
    @Autowired
    MarketCartMapper marketCartMapper;
    @Autowired
    MarketGoodsMapper marketGoodsMapper;


    final long ONE_DAY_MILIS = 1000L * 60 * 60 * 24;



    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");


    /**
     * @function_name selectlist
     * @param cartId
     * @param grouponRulesId
     * @idea 从 **Shiro安全框架** 获得当前登录用户的 *user_id* ，然后根据 *user_id* 和 *checked* 从 **market_cart表** 中获得所有 *goods_id*的集合 和 所有商品的 *price* 数据；再根据  *goods_id*的集合 从 **market_goods表** 中获得所有对应 *id* 的 *category_id* ，将其放入 *category_id*集合 里。
     *          根据 *user_id* 从 **market_coupon_user表** 中获得对应 *user_id* 的所有数据，包括 *coupon_id* 。再根据每条数据的 *coupon_id* 从 **market_coupon表** 中获得另一部分的数据。最后将所有数据返回。
     * @return com.cskaoyan.bean.vo.wx.coupon.WxCouponListVo
     * @author MoJunXiang
     * @since 2022/09/11 20:50
     */
    @Override
    public WxCouponListVo selectlist(Integer cartId, Integer grouponRulesId) {
        // 返回值
        WxCouponListVo selectlistVo = new WxCouponListVo();
        List<WxCouponMylistCouponVo> list = new ArrayList<>();
        selectlistVo.setList(list);

        // 从 Shiro安全框架 获得 userId
        Subject subject = SecurityUtils.getSubject();
        MarketUser principal = (MarketUser) subject.getPrincipals().getPrimaryPrincipal();
        Integer userId = principal.getId();

        /*TODO:
            1、从 market_cart表 中拿到所有 goods_id ；
            2、再根据从 market_cart表 中拿到的 cartGoodsIdList ，从 market_goods表 中拿到其中所有
                商品的 category_id
            3、拿到
                1）当前 商品id 对应的 price
                2）当前所有 category_id 相同的 商品 的 price总和
                3）当前所有 商品 的 price总和 */
        MarketCartExample example = new MarketCartExample();
        MarketCartExample.Criteria criteria = example.createCriteria();
        if (cartId == 0) {
            criteria.andCheckedEqualTo(true);
        }
        criteria.andUserIdEqualTo(userId);
        List<MarketCart> cartList = marketCartMapper.selectByExample(example);
        // 1、从 market_cart表 中拿到所有 goods_id
        ArrayList<Integer> cartGoodsIdList = new ArrayList<>();
        /* 2、根据从 market_cart表 中拿到的 cartGoodsIdList ，从 market_goods表 中拿到其中所有
         * 商品的 category_id */
        ArrayList<Integer> cartGoodsCategoryIdList = new ArrayList<>();
        // 3、
            // 1）当前 商品id 对应的 price
        HashMap<Integer, Double> cartGoodsIdPriceMap = new HashMap<>();
            // 2）当前所有 category_id 相同的 商品 的 price总和
        HashMap<Integer, Double> cartGoodsCategoryIdPriceMap = new HashMap<>();
            // 3）当前所有 商品 的 price总和
        double totalPrice = 0.0;
        for (MarketCart cart : cartList) {
            // 1、从 market_cart表 中拿到所有 goods_id
            Integer goodsId = cart.getGoodsId();
            cartGoodsIdList.add(goodsId);

            /* 2、根据从 market_cart表 中拿到的 cartGoodsIdList ，从 market_goods表 中拿到其中所有
             * 商品的 category_id */
            MarketGoods marketGoods = marketGoodsMapper.selectByPrimaryKey(goodsId);
            Integer categoryId = marketGoods.getCategoryId();
            cartGoodsCategoryIdList.add(categoryId);

            // 3、
            BigDecimal priceDecimal = cart.getPrice();
            double price = priceDecimal.doubleValue();
                // 1）当前 商品id 对应的 price
            cartGoodsIdPriceMap.put(goodsId, price);
                // 2）当前所有 category_id 相同的 商品 的 price总和
            Double categoryPrice = cartGoodsCategoryIdPriceMap.get(categoryId);
            if (categoryPrice == null) {
                cartGoodsCategoryIdPriceMap.put(categoryId, price);
            } else {
                categoryPrice = categoryPrice + price;
                cartGoodsCategoryIdPriceMap.put(categoryId, categoryPrice);
            }

                // 3）当前所有 商品 的 price总和
            totalPrice = totalPrice + price;
        }




        // 根据 user_id 从 market_coupon_user表 中拿到 coupon_id 及其余数据
        MarketCouponUserExample userExample = new MarketCouponUserExample();
        MarketCouponUserExample.Criteria userCriteria = userExample.createCriteria();
        userCriteria.andUserIdEqualTo(userId);
        List<MarketCouponUser> couponUserList = marketCouponUserMapper.selectByExample(userExample);

        for (MarketCouponUser couponUser : couponUserList) {

            Integer id = couponUser.getId();
            Integer couponId = couponUser.getCouponId();
            Date startTime = couponUser.getStartTime();
            Date endTime = couponUser.getEndTime();
            Short status = couponUser.getStatus();

            // 从 market_coupon表 中拿出 name , desc , tag, min, discount
            MarketCoupon coupon = marketCouponMapper.selectByPrimaryKey(couponId);
            Short goodsType = coupon.getGoodsType();
            Integer[] goodsValueArr = coupon.getGoodsValue();
            String name = coupon.getName();
            String desc = coupon.getDesc();
            String tag = coupon.getTag();
            BigDecimal min = coupon.getMin();
            BigDecimal discount = coupon.getDiscount();

            WxCouponMylistCouponVo selectlistCouponVo = new WxCouponMylistCouponVo();

            // 封装返回的 selectlistCouponVo
            /*TODO:重点
                1、根据 coupon 的 status 判断是否能用
*                   1） 0    —— true
*                   2） 其他 —— false
            *   2、得根据 coupon 的 goods_type 来判断 当前优惠卷 的 限定商品范围
             *      1）若是 0 —— available = true
             *      2）若是 1 ——根据从 market_cart表 中获得的所有 goods_id ，从
             *                   market_goods表 中查出其对应的所有 category_id ，
             *                  判断是否有 category_id 在 market_coupon 的
             *                   goods_value 内，
             *                  即 cartGoodsCategoryIdList 和 goodsValueArr 是否相交
             *                  有   —— ture
             *                  没有 —— false
 *                  3）若是 2 ——根据从 market_cart表 中获得的所有 goods_id ，判
 *                              断其是否有 goods_id 在 market_coupon 的 goods_value 内
 *                              即 cartGoodsIdList 和 goodsValueArr 是否相交
 *                              有   —— true
 *                              没有 —— false
*                3、得根据 coupon 的 min 来判断在范围内的商品的 总价 是否达到使用
*                    coupon 的最低价
*                   1）若是 0 ——判断 totalPrice 是否大于等于 min
*                                   是—— true
*                                   否—— false
             *      2）若是 1 ——判断 goodsValueArr 中的 cateforyId 在
                                 cartGoodsCategoryIdPriceMap 中的对应值
                                 cartGoodsCategoryIdPrice 是否大于等于 min
                                    是—— true
                                    否—— false
 *                  3）若是 2 ——判断 goodsValueArr 中的 goodsId 在
                                 cartGoodsIdPriceMap 中的对应值 cartGoodsIdPrice
                                是否大于等于 min
                                    是—— true
                                    否—— false
*               */

            boolean available = false;
            // 1、判断 status
            if (status.intValue() == 0) {
                // 2、根据 coupon 的 goods_type 来判断 当前优惠卷 的 限定商品范围
                if (goodsType.intValue() == 0) {
                    /*3、得根据 coupon 的 min 来判断在范围内的商品的 总价 是否
                        达到使用 coupon 的最低价*/
                    if (totalPrice >= min.doubleValue()) {
                        available = true;
                        selectlistCouponVo.setAvailable(available);
                    }
                } else if (goodsType.intValue() == 1) {
                    // 2、若是 1 ，判断 cartGoodsCategoryIdList 和 goodsValueArr 是否相交
                    for (Integer goodsValueGCId : goodsValueArr) {
                        available = cartGoodsCategoryIdList.contains(goodsValueGCId);
                        /*3、得根据 coupon 的 min 来判断在范围内的商品的 总价 是否
                            达到使用 coupon 的最低价*/
                        if (available == true) {
                            Double cartGoodsCategoryIdPrice = cartGoodsCategoryIdPriceMap.get(goodsValueGCId);
                            if (cartGoodsCategoryIdPrice >= min.doubleValue()) {
                                available = true;
                                selectlistCouponVo.setAvailable(available);
                                break;
                            }
                        }
                    }
                } else if (goodsType.intValue() == 2) {
                    // 2、若是 2 ，判断 cartGoodsIdList 和 goodsValueArr 是否相交
                    for (Integer goodsValueGId : goodsValueArr) {
                        available = cartGoodsIdList.contains(goodsValueGId);
                        /*3、得根据 coupon 的 min 来判断在范围内的商品的 总价 是否
                            达到使用 coupon 的最低价*/
                        if (available == true) {
                            Double cartGoodsIdPrice = cartGoodsIdPriceMap.get(goodsValueGId);
                            if (cartGoodsIdPrice >= min.doubleValue()) {
                                available = true;
                                selectlistCouponVo.setAvailable(available);
                                break;
                            }
                        }
                    }
                }
            } else {
                selectlistCouponVo.setAvailable(false);
            }

            selectlistCouponVo.setCid(couponId);
            selectlistCouponVo.setDesc(desc);
            selectlistCouponVo.setDiscount(discount.intValue());
            selectlistCouponVo.setId(id);
            String start_time = transeferDate2String(startTime);
            selectlistCouponVo.setStartTime(start_time);
            String end_time = transeferDate2String(endTime);
            selectlistCouponVo.setEndTime(end_time);
            selectlistCouponVo.setMin(min.intValue());
            selectlistCouponVo.setTag(tag);
            selectlistCouponVo.setName(name);

            list.add(selectlistCouponVo);
        }


        selectlistVo.setLimit(couponUserList.size());
        selectlistVo.setPage(1);
        selectlistVo.setPages(1);
        selectlistVo.setTotal(couponUserList.size());

        return selectlistVo;
    }


    /**
     * @function_name list
     * @param page
     * @param limit
     * @idea 返回 **market_coupon表** 中所有数据
     * @return com.cskaoyan.bean.vo.wx.coupon.WxCouponListVo
     * @author MoJunXiang
     * @since 2022/09/11 21:53
     */
    @Override
    public WxCouponListVo list(Integer page, Integer limit) {
        // 返回值
        WxCouponListVo listVo = new WxCouponListVo();
        ArrayList<WxCouponListCouponVo> list = new ArrayList<>();
        listVo.setList(list);


        // 从数据库 market_coupon表 中获取所有 优惠券 数据
        PageHelper.startPage(page, limit);
        List<MarketCoupon> couponList = marketCouponMapper.selectByExample(new MarketCouponExample());
        PageInfo<MarketCoupon> pageInfo = new PageInfo<>(couponList);

        // 将从 market_coupon表 中查出的数据放入 list 中
        for (MarketCoupon coupon : couponList) {
            Integer id = coupon.getId();
            String name = coupon.getName();
            String desc = coupon.getDesc();
            String tag = coupon.getTag();
            BigDecimal discount = coupon.getDiscount();
            BigDecimal min = coupon.getMin();
            Short timeType = coupon.getTimeType();
            long days = 0;
            if (timeType.intValue() == 0) {
                days = coupon.getDays();
            } else {
                Date endTime = coupon.getEndTime();
                Date startTime = coupon.getStartTime();

                days = Math.abs((endTime.getTime() - startTime.getTime()) / ONE_DAY_MILIS);
            }

            WxCouponListCouponVo couponVo = new WxCouponListCouponVo();
            couponVo.setDays(days);
            couponVo.setDesc(desc);
            couponVo.setDiscount(discount.intValue());
            couponVo.setId(id);
            couponVo.setMin(min.intValue());
            couponVo.setName(name);
            couponVo.setTag(tag);

            list.add(couponVo);
        }

        // 将其余数据放入 listVo 中
        listVo.setLimit(limit);
        listVo.setPage(page);
        listVo.setPages(pageInfo.getPages());
        listVo.setTotal(((int) pageInfo.getTotal()));

        return listVo;
    }



    /**
     * @function_name mylist
     * @param page
     * @param limit
     * @param status
     * @idea 从 **Shiro安全框架** 拿到当前登录对象的 *user_id* ，然后根据 *user_id* 从 **market_coupon_user表** 中获得一部分数据，再根据每条数据的 *coupon_id* 从 **market_coupon表** 中获得另一部分的数据。最后将所有数据返回。
     * @return com.cskaoyan.bean.vo.wx.coupon.WxCouponListVo
     * @author MoJunXiang
     * @since 2022/09/11 23:50
     */
    @Override
    public WxCouponListVo mylist(Integer page, Integer limit, Integer status) {
        // 返回值
        WxCouponListVo listVo = new WxCouponListVo();
        ArrayList<WxCouponMylistCouponVo> list = new ArrayList<>();
        listVo.setList(list);


        // 拿到登录后保存的 用户id/user_id
        Subject subject = SecurityUtils.getSubject();
        MarketUser principal = (MarketUser) subject.getPrincipals().getPrimaryPrincipal();
        Integer userId = principal.getId();

        // 根据 user_id 从 market_coupon_user表 中拿到 coupon_id 及其余数据
        MarketCouponUserExample userExample = new MarketCouponUserExample();
        MarketCouponUserExample.Criteria userCriteria = userExample.createCriteria();
        userCriteria.andUserIdEqualTo(userId);
        userCriteria.andStatusEqualTo(status.shortValue());
        List<MarketCouponUser> couponUserList = marketCouponUserMapper.selectByExample(userExample);

        for (MarketCouponUser couponUser : couponUserList) {

            Integer id = couponUser.getId();
            Integer couponId = couponUser.getCouponId();
            Date startTime = couponUser.getStartTime();
            Date endTime = couponUser.getEndTime();

            // 从 market_coupon表 中拿出 name , desc , tag, min, discount
            MarketCoupon coupon = marketCouponMapper.selectByPrimaryKey(couponId);
            String name = coupon.getName();
            String desc = coupon.getDesc();
            String tag = coupon.getTag();
            BigDecimal min = coupon.getMin();
            BigDecimal discount = coupon.getDiscount();

            WxCouponMylistCouponVo mylistCouponVo = new WxCouponMylistCouponVo();
            mylistCouponVo.setAvailable(status == 0);
            mylistCouponVo.setCid(couponId);
            mylistCouponVo.setDesc(desc);
            mylistCouponVo.setDiscount(discount.intValue());
            mylistCouponVo.setId(id);
            String start_time = transeferDate2String(startTime);
            mylistCouponVo.setStartTime(start_time);
            String end_time = transeferDate2String(endTime);
            mylistCouponVo.setEndTime(end_time);
            mylistCouponVo.setMin(min.intValue());
            mylistCouponVo.setTag(tag);
            mylistCouponVo.setName(name);

            list.add(mylistCouponVo);
        }


        listVo.setLimit(couponUserList.size());
        listVo.setPage(1);
        listVo.setPages(1);
        listVo.setTotal(couponUserList.size());

        return listVo;
    }



    /**
     * @function_name receive
     * @param couponId
     * @idea 接收到传来的 *couponId* ，根据 **market_coupon表** 里对应 *id* 的数据，根据 *total* ， *limit* ， *goods_type* ， *goods_value* ， *time_type* ， *days* ， *start_time* ， *end_time* 进行一系列判断，将判断得来的数据和创建时的时间数据放入 *MarketCouponUser对象couponUser* 中，将其插入 **market_coupon_user表** 里。
     * @return int
     * @author MoJunXiang
     * @since 2022/09/12 19:58
     */
    @Override
    public int receive(Integer couponId) {
        // 拿到登陆后保存的 用户id/user_id
        Subject subject = SecurityUtils.getSubject();
        MarketUser principal = (MarketUser) subject.getPrincipals().getPrimaryPrincipal();
        Integer userId = principal.getId();

        /*从 market_coupon表 中查出需要往 market_coupon_user表 中插入的数据，
        * 再补充另外一些数据，构成一条能插入 market_coupon_user表 的数据，并
        * 将其插入*/
        // 要插入数据库的数据
        MarketCouponUser couponUser = new MarketCouponUser();
        /*放入 user_id, coupon_id, status, used_time(null), order_id(null), add_time(新建),
         update_time(新建)*/
        couponUser.setUserId(userId);
        couponUser.setCouponId(couponId);
        couponUser.setStatus(Short.valueOf("0"));
        Date addTime = formatDate(new Date());
        couponUser.setAddTime(addTime);
        Date updateTime = formatDate(new Date());
        couponUser.setUpdateTime(updateTime);

        // 查 market_coupon表
        MarketCoupon coupon = marketCouponMapper.selectByPrimaryKey(couponId);
        /*从 coupon 中查出 start_time(需经判断), end_time(须经判断), limit(需拿来进行判断)
        * total(需拿来进行判断), id(需拿来进行 total 数量更新)*/
        Short timeType = coupon.getTimeType();
        if (timeType.intValue() == 0) {
            couponUser.setStartTime(addTime);
            Short days = coupon.getDays();
            long endTimeMilis = addTime.getTime() + days * ONE_DAY_MILIS;
            Date endTime = formatDate(new Date(endTimeMilis));
            couponUser.setEndTime(endTime);
        } else {
            Date startTime = formatDate(coupon.getStartTime());
            Date endTime = formatDate(coupon.getEndTime());
            couponUser.setStartTime(startTime);
            couponUser.setEndTime(endTime);
        }

        // 获取 limit(需拿来进行判断)
        Short limit = coupon.getLimit();
        // 获取 total(需拿来进行判断)
        Integer total = coupon.getTotal();
        // 获取 id(需拿来进行 total 数量更新)
        Integer id = coupon.getId();

        /*TODO:判断当前用户是否能成功领取当前 优惠券
            具体分支情况见 项目二 小程序-优惠券-receive接口 领取条件分析"组织结构图
        *   成功：插入 couponUser ，返回 0
        *   失败：根据情况返回
        *       1 —— 来迟啦＞﹏＜优惠卷已领光
                2 —— 领太多啦（⊙ｏ⊙）！已经超过领取数量上限*/
        /*必须要使用到的数据：
        *   market_coupon_user表  里已有的 coupon_id 等于当前 coupon的id 的数据
        *  的  数量 */
        MarketCouponUserExample example = new MarketCouponUserExample();
        MarketCouponUserExample.Criteria criteria = example.createCriteria();
        criteria.andCouponIdEqualTo(couponId);
        List<MarketCouponUser> couponUserList = marketCouponUserMapper.selectByExample(example);
        /*需要的 market_coupon_user表 里已有的 coupon_id 等于当前 coupon的id 的数据
         *的 数量<——>couponReceivedAmount */
        int couponReceivedAmount = couponUserList.size();
        // 符合领取条件后，插入数据影响行数
        int affectedRow = 0;
        // 符合领取条件，插入数据后，更新 当前优惠卷储量total 的影响行数
        int updateAffectedRow = 0;
        // 第一层判断<——> total 判断
        if (total == 0) {
            // 第二层判断<——> limit 判断
            if (limit == 0) {
                // 用户可以无限领取    信息：领取成功ψ(｀∇´)ψ
                affectedRow = marketCouponUserMapper.insertSelective(couponUser);
                return 0;
            } else {
                /* 第三层判断
                * <——>
                *  market_coupon_user表 里已有的 coupon_id 等于当前 coupon的id 的
                * 数据的 数量couponReceivedAmount 是否仍在 limit 限制的 领取数量
                * 区间内，即是否还能领取？
                    <——>
                   couponReceivedAmount < limit ？*/
                if (couponReceivedAmount < limit) {
                    // 是            信息：领取成功ψ(｀∇´)ψ
                    affectedRow = marketCouponUserMapper.insertSelective(couponUser);
                    return 0;
                } else {
                    // 否        信息：领太多啦（⊙ｏ⊙）！已经超过领取数量上限
                    return 2;
                }
            }
        // 第一层判断<——> total 判断
        } else if (total > 0) {
            // 第二层判断<——> limit 判断
            if (limit == 0) {
                // 用户可以无限领取    信息：领取成功ψ(｀∇´)ψ    0
                affectedRow = marketCouponUserMapper.insertSelective(couponUser);
                MarketCoupon marketCoupon = new MarketCoupon();
                if (total == 1) {
                    /*如果 储量total 只剩下 1 ，为了不要让 total-1 后变成表示 无限 的
                    *  0 ，这里让 total - 2 ，从 储量total==1 的状态变成
                    *  储量total为空 的状态*/
                    marketCoupon.setTotal(total - 2);
                } else {
                    marketCoupon.setTotal(total - 1);
                }
                marketCoupon.setId(id);
                updateAffectedRow = marketCouponMapper.updateByPrimaryKeySelective(marketCoupon);

                return 0;
            } else {
                /* 第三层判断
                * <——>
                *  market_coupon_user表 里已有的 coupon_id 等于当前 coupon的id 的
                * 数据的 数量couponReceivedAmount 是否仍在 limit 限制的 领取数量
                * 区间内，即是否还能领取？
                    <——>
                   couponReceivedAmount < limit ？*/
                if (couponReceivedAmount < limit) {
                    // 是            信息：领取成功ψ(｀∇´)ψ    0
                    affectedRow = marketCouponUserMapper.insertSelective(couponUser);
                    MarketCoupon marketCoupon = new MarketCoupon();
                    if (total == 1) {
                        /*如果 储量total 只剩下 1 ，为了不要让 total-1 后变成表示 无限 的
                         *  0 ，这里让 total - 2 ，从 储量total==1 的状态变成
                         *  储量total为空 的状态*/
                        marketCoupon.setTotal(total - 2);
                    } else {
                        marketCoupon.setTotal(total - 1);
                    }
                    marketCoupon.setId(id);
                    updateAffectedRow = marketCouponMapper.updateByPrimaryKeySelective(marketCoupon);
                    return 0;
                } else {
                    // 否   信息：领太多啦（⊙ｏ⊙）！已经超过领取数量上限   2
                    return 2;
                }
            }

            // 第一层判断<——> total 判断
        } else {
            // 否    信息：来迟啦＞﹏＜优惠卷已领光    1
            return 1;
        }


    }



    @Override
    public HashMap<String, Object> exchange(String code) {
        // 返回值
        HashMap<String, Object> voMap = new HashMap<>();
        WxCouponExchangeCouponVo exchangeCouponVo = new WxCouponExchangeCouponVo();
        Integer resultCode = 0;
        voMap.put("vo", exchangeCouponVo);
        voMap.put("resultCode", resultCode);

        // 从 Shiro安全框架 获取 userId
        Subject subject = SecurityUtils.getSubject();
        MarketUser principal = (MarketUser) subject.getPrincipals().getPrimaryPrincipal();
        Integer userId = principal.getId();


        /*根据 兑换码code ，从 market_coupon表 中查到
          time_type(用于判断是否过期), days/start_time + end_time<-->用于判断是否过期
          total(用于判断储量是否足够)
          ----limit(用于判断是否有领取数量限制——定为定值1，排除考虑)
          coupon_id(用于从 market_coupon_user表 中查询 当前用户 是否已领取过 当前coupon )*/
        MarketCouponExample couponExample = new MarketCouponExample();
        MarketCouponExample.Criteria criteria = couponExample.createCriteria();
        criteria.andCodeEqualTo(code);
        List<MarketCoupon> marketCoupon = marketCouponMapper.selectByExample(couponExample);
        MarketCoupon coupon = marketCoupon.get(0);
        // time_type(用于判断是否过期), days/start_time + end_time<-->用于判断是否过期
        Short timeType = coupon.getTimeType();
        Short days = coupon.getDays();
        Date startTime = coupon.getStartTime();
        Date endTime = coupon.getEndTime();
        // total(用于判断储量是否足够)
        Integer total = coupon.getTotal();
        // coupon_id(用于从 market_coupon_user表 中查询 当前用户 是否已领取过 当前coupon )
        Integer couponId = coupon.getId();

        /*根据 coupon_id ，从 market_coupon_user表 中查询 当前用户 是否已领取过
          当前coupon*/
        MarketCouponUserExample couponUserExample = new MarketCouponUserExample();
        MarketCouponUserExample.Criteria couponUserCriteria = couponUserExample.createCriteria();
        couponUserCriteria.andCouponIdEqualTo(couponId);
        List<MarketCouponUser> marketCouponUser = marketCouponUserMapper.selectByExample(couponUserExample);

        // 判断是否更新 当前优惠卷 的 储量total
        int updateAffectedRow = 0;

        /* 第一层<——>判断是否过时 */
        // timeType==0  用days，不过时
        if (timeType == 0) {
            // 第二层<——>判断储量
            // 储量total==0  储量total无限
            if (total == 0) {
                // 第三层<——>判断 当前用户 是否已领取 当前优惠券
                if (marketCouponUser.size() == 0) {
                    //  当前用户 还没有领取 当前优惠券
                        /*往 market_coupon_user表 中插入数据
                        <——>
                         当前用户 领取 当前优惠券 */
                    String name = coupon.getName();
                    String desc = coupon.getDesc();
                    String tag = coupon.getTag();
                    BigDecimal min = coupon.getMin();
                    BigDecimal discount = coupon.getDiscount();
                    Short status = coupon.getStatus();

                    MarketCouponUser couponUser = new MarketCouponUser();
                    couponUser.setCouponId(couponId);
                    couponUser.setStatus(status);
                    couponUser.setUserId(userId);
                    // 使用 当前时间 来当成 start_time
                    long startTimeMillis = System.currentTimeMillis();
                    Date start_time = new Date(startTimeMillis);
                    // 用 days 和 start_time 来获得 end_time
                    Date end_time = new Date(startTimeMillis + days * ONE_DAY_MILIS);
                    couponUser.setStartTime(start_time);
                    couponUser.setEndTime(end_time);
                    couponUser.setAddTime(new Date());
                    couponUser.setUpdateTime(new Date());
                    couponUser.setDeleted(false);

                    int insertRows = marketCouponUserMapper.insertSelective(couponUser);

                    // 设置 返回值exchangeCouponVo
                    exchangeCouponVo.setId(couponUser.getId());
                    exchangeCouponVo.setAvailable(true);
                    exchangeCouponVo.setCid(couponId);
                    exchangeCouponVo.setName(name);
                    exchangeCouponVo.setDesc(desc);
                    exchangeCouponVo.setTag(tag);
                    exchangeCouponVo.setMin(min.intValue());
                    exchangeCouponVo.setDiscount(discount.intValue());
                    // 使用 当前时间 来当成 start_time
                    String start_time_Str = transeferDate2String(start_time);
                    exchangeCouponVo.setStartTime(start_time_Str);
                    // 用 days 和 start_time 来获得 end_time
                    String end_time_Str = transeferDate2String(end_time);
                    exchangeCouponVo.setEndTime(end_time_Str);

                    // 设置 返回结果码resultCode
                    resultCode = 0;


                } else {
                    //  当前用户 已领取 当前优惠券
                    resultCode = 2;
                }
                // 第二层<——>判断储量
                // 储量total!=0  储量total 有限但仍有剩余
            } else if (total > 0) {
                // 第三层<——>判断 当前用户 是否已领取 当前优惠券
                if (marketCouponUser.size() == 0) {
                    //  当前用户 还没有领取 当前优惠券
                        /*往 market_coupon_user表 中插入数据
                        <——>
                         当前用户 领取 当前优惠券 */
                    String name = coupon.getName();
                    String desc = coupon.getDesc();
                    String tag = coupon.getTag();
                    BigDecimal min = coupon.getMin();
                    BigDecimal discount = coupon.getDiscount();
                    Short status = coupon.getStatus();

                    MarketCouponUser couponUser = new MarketCouponUser();
                    couponUser.setCouponId(couponId);
                    couponUser.setStatus(status);
                    couponUser.setUserId(userId);
                    // 使用 当前时间 来当成 start_time
                    long startTimeMillis = System.currentTimeMillis();
                    Date start_time = new Date(startTimeMillis);
                    // 用 days 和 start_time 来获得 end_time
                    Date end_time = new Date(startTimeMillis + days * ONE_DAY_MILIS);
                    couponUser.setStartTime(start_time);
                    couponUser.setEndTime(end_time);
                    couponUser.setAddTime(new Date());
                    couponUser.setUpdateTime(new Date());
                    couponUser.setDeleted(false);

                    int insertRows = marketCouponUserMapper.insertSelective(couponUser);

                    // 设置 返回值exchangeCouponVo
                    exchangeCouponVo.setId(couponUser.getId());
                    exchangeCouponVo.setAvailable(true);
                    exchangeCouponVo.setCid(couponId);
                    exchangeCouponVo.setName(name);
                    exchangeCouponVo.setDesc(desc);
                    exchangeCouponVo.setTag(tag);
                    exchangeCouponVo.setMin(min.intValue());
                    exchangeCouponVo.setDiscount(discount.intValue());
                    // 使用 当前时间 来当成 start_time
                    String start_time_Str = transeferDate2String(start_time);
                    exchangeCouponVo.setStartTime(start_time_Str);
                    // 用 days 和 start_time 来获得 end_time
                    String end_time_Str = transeferDate2String(end_time);
                    exchangeCouponVo.setEndTime(end_time_Str);

                    // 设置 返回结果码resultCode
                    resultCode = 0;

                    // 更新 market_coupon表 中对应 优惠券 的 储量total
                    MarketCoupon marketCouponUpdate = new MarketCoupon();
                    if (total == 1) {
                        /*如果 储量total 只剩下 1 ，为了不要让 total-1 后变成表示 无限 的
                         *  0 ，这里让 total - 2 ，从 储量total==1 的状态变成
                         *  储量total为空 的状态*/
                        marketCouponUpdate.setTotal(total - 2);
                    } else {
                        marketCouponUpdate.setTotal(total - 1);
                    }
                    marketCouponUpdate.setId(couponId);
                    updateAffectedRow = marketCouponMapper.updateByPrimaryKeySelective(marketCouponUpdate);
                } else {
                    //  当前用户 已领取 当前优惠券
                    resultCode = 2;
                }

                // 第二层<——>判断储量
                // 储量total!=0  储量total 有限且没有剩余
            } else {
                // 否    信息：优惠卷已领光＞﹏＜    1
                resultCode = 1;
            }

        // timeType==1  需要处理 startTime 和 endTime 来进行判断
        } else {
            long currentTimeMillis = System.currentTimeMillis();
            long endTimeMillis = endTime.getTime();
            // 如果 当前时间戳<endTime时间戳 ，说明没过时
            if (currentTimeMillis < endTimeMillis) {
                // 第二层<——>判断储量
                // 储量total==0  储量total无限
                if (total == 0) {
                    // 第三层<——>判断 当前用户 是否已领取 当前优惠券
                    if (marketCouponUser.size() == 0) {
                        //  当前用户 还没有领取 当前优惠券
                        /*往 market_coupon_user表 中插入数据
                        <——>
                         当前用户 领取 当前优惠券 */
                        String name = coupon.getName();
                        String desc = coupon.getDesc();
                        String tag = coupon.getTag();
                        BigDecimal min = coupon.getMin();
                        BigDecimal discount = coupon.getDiscount();
                        Short status = coupon.getStatus();

                        MarketCouponUser couponUser = new MarketCouponUser();
                        couponUser.setCouponId(couponId);
                        couponUser.setStatus(status);
                        couponUser.setUserId(userId);
                        couponUser.setStartTime(startTime);
                        couponUser.setEndTime(endTime);
                        couponUser.setAddTime(new Date());
                        couponUser.setUpdateTime(new Date());
                        couponUser.setDeleted(false);

                        int insertRows = marketCouponUserMapper.insertSelective(couponUser);

                        // 设置 返回值exchangeCouponVo
                        exchangeCouponVo.setId(couponUser.getId());
                        exchangeCouponVo.setAvailable(true);
                        exchangeCouponVo.setCid(couponId);
                        exchangeCouponVo.setName(name);
                        exchangeCouponVo.setDesc(desc);
                        exchangeCouponVo.setTag(tag);
                        exchangeCouponVo.setMin(min.intValue());
                        exchangeCouponVo.setDiscount(discount.intValue());
                        String start_time = transeferDate2String(startTime);
                        exchangeCouponVo.setStartTime(start_time);
                        String end_time = transeferDate2String(endTime);
                        exchangeCouponVo.setEndTime(end_time);

                        // 设置 返回结果码resultCode
                        resultCode = 0;
                    } else {
                        //  当前用户 已领取 当前优惠券
                        resultCode = 2;
                    }
                // 第二层<——>判断储量
                // 储量total!=0  储量total 有限但仍有剩余
                } else if (total > 0) {
                    // 第三层<——>判断 当前用户 是否已领取 当前优惠券
                    if (marketCouponUser.size() == 0) {
                        //  当前用户 还没有领取 当前优惠券
                        /*往 market_coupon_user表 中插入数据
                        <——>
                         当前用户 领取 当前优惠券 */
                        String name = coupon.getName();
                        String desc = coupon.getDesc();
                        String tag = coupon.getTag();
                        BigDecimal min = coupon.getMin();
                        BigDecimal discount = coupon.getDiscount();
                        Short status = coupon.getStatus();

                        MarketCouponUser couponUser = new MarketCouponUser();
                        couponUser.setCouponId(couponId);
                        couponUser.setStatus(status);
                        couponUser.setUserId(userId);
                        couponUser.setStartTime(startTime);
                        couponUser.setEndTime(endTime);
                        couponUser.setAddTime(new Date());
                        couponUser.setUpdateTime(new Date());
                        couponUser.setDeleted(false);

                        int insertRows = marketCouponUserMapper.insertSelective(couponUser);

                        // 设置 返回值exchangeCouponVo
                        exchangeCouponVo.setId(couponUser.getId());
                        exchangeCouponVo.setAvailable(true);
                        exchangeCouponVo.setCid(couponId);
                        exchangeCouponVo.setName(name);
                        exchangeCouponVo.setDesc(desc);
                        exchangeCouponVo.setTag(tag);
                        exchangeCouponVo.setMin(min.intValue());
                        exchangeCouponVo.setDiscount(discount.intValue());
                        String start_time = transeferDate2String(startTime);
                        exchangeCouponVo.setStartTime(start_time);
                        String end_time = transeferDate2String(endTime);
                        exchangeCouponVo.setEndTime(end_time);

                        // 设置 返回结果码resultCode
                        resultCode = 0;


                        // 更新 market_coupon表 中对应 优惠券 的 储量total
                        MarketCoupon marketCouponUpdate = new MarketCoupon();
                        if (total == 1) {
                            /*如果 储量total 只剩下 1 ，为了不要让 total-1 后变成表示 无限 的
                             *  0 ，这里让 total - 2 ，从 储量total==1 的状态变成
                             *  储量total为空 的状态*/
                            marketCouponUpdate.setTotal(total - 2);
                        } else {
                            marketCouponUpdate.setTotal(total - 1);
                        }
                        marketCouponUpdate.setId(couponId);
                        updateAffectedRow = marketCouponMapper.updateByPrimaryKeySelective(marketCouponUpdate);
                    } else {
                        //  当前用户 已领取 当前优惠券
                        resultCode = 2;
                    }

                // 第二层<——>判断储量
                // 储量total!=0  储量total 有限且没有剩余
                } else {
                    // 否    信息：优惠卷已领光＞﹏＜    1
                    resultCode = 1;
                }
            // 否则说明过时
            } else {
                // 信息：来迟啦，优惠卷已过期＞︿＜    3
                resultCode = 3;
            }
        }
        voMap.put("resultCode", resultCode);


        return voMap;
    }


    private String transeferDate2String(Date date) {
        return dateFormat.format(date);
    }

    private Date formatDate(Date date) {
        String dateStr = dateFormat.format(date);
        Date formate = null;
        try {
            formate = dateFormat.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        } finally {
            return formate;
        }
    }
}
